<?php
/**
 * <a href="http://www.qiniu.com/" target="_blank">七牛</a> 附件上传插件，来自<a href="http://doudou.me">兜兜</a>的BAE插件...
 * 
 * @package QNUpload
 * @author rakiy
 * @version 1.0.0
 * @link http://ysido.com
 * @date 2013-12-26
 */

class QNUpload_Plugin implements Typecho_Plugin_Interface
{
    /**
     * 激活插件方法,如果激活失败,直接抛出异常
     * 
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function activate()
    {
        Typecho_Plugin::factory('Widget_Upload')->uploadHandle = array('QNUpload_Plugin', 'uploadHandle');
        Typecho_Plugin::factory('Widget_Upload')->modifyHandle = array('QNUpload_Plugin', 'modifyHandle');
        Typecho_Plugin::factory('Widget_Upload')->deleteHandle = array('QNUpload_Plugin', 'deleteHandle');
        Typecho_Plugin::factory('Widget_Upload')->attachmentHandle = array('QNUpload_Plugin', 'attachmentHandle');
        Typecho_Plugin::factory('Widget_Upload')->attachmentDataHandle = array('QNUpload_Plugin', 'attachmentDataHandle');
    }
    
    /**
     * 禁用插件方法,如果禁用失败,直接抛出异常
     * 
     * @static
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function deactivate(){}
    
    /**
     * 获取插件配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form 配置面板
     * @return void
     */
    public static function config(Typecho_Widget_Helper_Form $form)
    {
        $ak = new Typecho_Widget_Helper_Form_Element_Text('ak', 
        NULL, '',
        _t('Access Key'),
        _t('<a href="https://portal.qiniu.com/setting/key" target="_blank">获取Access Key</a>'));
        $form->addInput($ak);

        $sk = new Typecho_Widget_Helper_Form_Element_Text('sk', 
        NULL, '',
        _t('Secure Key'),
        _t('<a href="https://portal.qiniu.com/setting/key" target="_blank">获取Secure Key</a>'));
        $form->addInput($sk);

        $bucketName = new Typecho_Widget_Helper_Form_Element_Text('bucket',
        NULL, 'bucketName',
        _t('Bucket名称'),
        _t(''));
        $form->addInput($bucketName);

        $domain = new Typecho_Widget_Helper_Form_Element_Text('domain',
        NULL, 'http://',
        _t('绑定的域名,如果你想使用绑定了的域名,请填写，否则请留空,结尾不带/，形如 http://123.com'),
        _t(''));
        $form->addInput($domain);

    }
    
    /**
     * 个人用户的配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form
     * @return void
     */
    public static function personalConfig(Typecho_Widget_Helper_Form $form){}
    
    /**
     * 上传文件处理函数
     *
     * @access public
     * @param array $file 上传的文件
     * @return mixed
     */
    public static function uploadHandle($file)
    {
        if (empty($file['name'])) {
            return false;
        }

        $fileName = preg_split("(\/|\\|:)", $file['name']);
        $file['name'] = array_pop($fileName);
        
        //获取扩展名
        $ext = '';
        $part = explode('.', $file['name']);
        if (($length = count($part)) > 1) {
            $ext = strtolower($part[$length - 1]);
        }

        if (!Widget_Upload::checkFileType($ext)) {
            return false;
        }

        $options = Typecho_Widget::widget('Widget_Options');        

        $date = new Typecho_Date($options->gmtTime);

        //构建路径
        $path = $date->year . '/' . $date->month ;

        //获取文件名
        $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext;

        $path = $path . '/' . $fileName;

        if(!isset($file['tmp_name']) && !isset($file['bits'])) return false;      //若不包含文章，则直接退出

        self::initKeys();       //初始化

        $bucket = $options->plugin('QNUpload')->bucket;

        $tmpfile = isset($file['tmp_name']) ? $file['tmp_name'] : $file['bits'];    //上需要上传的文件

        $putPolicy = new Qiniu_RS_PutPolicy($bucket);

        $upToken = $putPolicy->Token(null);

        $putExtra = new Qiniu_PutExtra();

        $putExtra->Crc32 = 1;

        list($ret, $err) = Qiniu_PutFile($upToken, $path , $tmpfile , $putExtra);

        if($err !== null) return false;             //上传出错直接返回错误

        if (!isset($file['size'])) {

            $client = new Qiniu_MacHttpClient(null);

            list($ret, $err) = Qiniu_RS_Stat($client, $bucket, $fileName);

            if($err !== null) return false;             //获取出错则报错

            $file['size'] = $ret['filesize'];

        }
  
        //返回相对存储路径
        return array(
            'name' => $file['name'],
            'path' => $path,
            'size' => $file['size'],
            'type' => $ext,
            'mime' => Typecho_Common::mimeContentType($path)
        );
    }

    /**
     * 修改文件处理函数
     *
     * @access public
     * @param array $content 老文件
     * @param array $file 新上传的文件
     * @return mixed
     */
    public static function modifyHandle($content, $file)
    {
        if (empty($file['name'])) {
            return false;
        }

        $fileName = preg_split("(\/|\\|:)", $file['name']);
        $file['name'] = array_pop($fileName);
        
        //获取扩展名
        $ext = '';
        $part = explode('.', $file['name']);
        if (($length = count($part)) > 1) {
            $ext = strtolower($part[$length - 1]);
        }

        if ($content['attachment']->type != $ext) {
            return false;
        }

        //获取文件名
        $fileName = $content['attachment']->path;

        $path = $fileName;

        $options = Typecho_Widget::widget('Widget_Options');

        if(!isset($file['tmp_name']) && !isset($file['bits'])) return false;      //若不包含文章，则直接退出

        self::initKeys();       //初始化

        $bucket = $options->plugin('QNUpload')->bucket;

        $tmpfile = isset($file['tmp_name']) ? $file['tmp_name'] : $file['bits'];    //上需要上传的文件

        //上传之前先删除远程同名文件,无须报错，直接删除

        $client = new Qiniu_MacHttpClient(null);

        $err = Qiniu_RS_Delete($client, $bucket, $path);

        //开始上传

        $putPolicy = new Qiniu_RS_PutPolicy($bucket);

        $upToken = $putPolicy->Token(null);

        $putExtra = new Qiniu_PutExtra();

        $putExtra->Crc32 = 1;

        list($ret, $err) = Qiniu_PutFile($upToken, $path , $tmpfile , $putExtra);

        if($err !== null) return false;             //上传出错直接返回错误

        if (!isset($file['size'])) {

            $client = new Qiniu_MacHttpClient(null);

            list($ret, $err) = Qiniu_RS_Stat($client, $bucket, $fileName);

            if($err !== null) return false;             //获取出错则报错

            $file['size'] = $ret['filesize'];

        }
        //返回相对存储路径
        return array(
            'name' => $content['attachment']->name,
            'path' => $content['attachment']->path,
            'size' => $file['size'],
            'type' => $content['attachment']->type,
            'mime' => $content['attachment']->mime
        );
    }

    /**
     * 删除文件
     *
     * @access public
     * @param array $content 文件相关信息
     * @return string
     */
    public static function deleteHandle(array $content)
    {
        self::initKeys();
        $bucket = Helper::options()->plugin('QNUpload')->bucket;
        //空日志记录函数
        $client = new Qiniu_MacHttpClient(null);
        $err = Qiniu_RS_Delete($client, $bucket, $content['attachment']->path);
        return !$err;
    }

    /**
     * 获取实际文件绝对访问路径
     *
     * @access public
     * @param array $content 文件相关信息
     * @return string
     */
    public static function attachmentHandle(array $content)
    {
        //不采用bcs获取还签名的url
        $domain = Helper::options()->plugin('QNUpload')->domain;
        $tmp = preg_match('/http:\/\/[\w\d\.\-]+$/is', $domain);    //粗略验证域名
        if($tmp && !empty($domain)){
            $url = $domain . '/';
        }else{
            $bucket = Helper::options()->plugin('QNUpload')->bucket;
            $url = 'http://' . $bucket . '.u.qiniudn.com/';
        }
        return Typecho_Common::url($content['attachment']->path, $url);
    }

    /**
     * 获取实际文件数据
     *
     * @access public
     * @param array $content
     * @return string
     */
    public static function attachmentDataHandle(array $content)
    {
        self::initKeys();
        $bucket = Helper::options()->plugin('QNUpload')->bucket;
        //空日志记录函数

        $client = new Qiniu_MacHttpClient(null);

        list($ret, $err) = Qiniu_RS_Stat($client, $bucket, $fileName);

        if ($err === null) return $ret;

        return false;
    }

    /**
     * qn初始化
     *
     * @access public
     * @return object
     */
    public static function initKeys()
    {
        $options = Typecho_Widget::widget('Widget_Options')->plugin('QNUpload');
        require_once("qiniu/io.php");
        require_once("qiniu/rs.php");
        Qiniu_SetKeys($options->ak, $options->sk);
    }
}
